package com.ali.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain;

import static org.springframework.security.config.Customizer.withDefaults;

/**
 * Security配置类
 * EnableWebSecurity：开启Security自定义配置
 * EnableMethodSecurity：开启Security方法授权
 */
@EnableMethodSecurity
@EnableWebSecurity
@Configuration
public class WebSecurityConfig {
    /**
     * 内存用户管理器
     */
//    @Bean
//    public UserDetailsService userDetailsService() {
//        //基于内存的用户管理器
//        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
//        //创建密码编码器
//        PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
//        //创建用户
//        UserDetails userDetails = User.withUsername("admin").password("hello").passwordEncoder(passwordEncoder::encode).build();
//        //管理用户
//        manager.createUser(userDetails);
//        return manager;
//    }

    /**
     * 默认配置
     */
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        //授权
        http.authorizeHttpRequests(
                        authorize -> authorize
                                .requestMatchers("/user/all")
                                //设置请求权限
//                                .hasAuthority("USER_LIST")
                                //设置请求角色
                                .hasAnyRole("ADMIN", "USER")
                                //对所有请求开启授权保护
                                .anyRequest()
                                //已认证的请求会自动授权
                                .authenticated()
        );

        //登录，表单授权方式
        http.formLogin(form -> form
                //自定义登录页
                .loginPage("/login")
                //无需认证即可访问
                .permitAll()
                //自定义表单用户名，默认值为username
                .usernameParameter("username")
                //自定义表单密码，默认值为password
                .passwordParameter("password")
                //登陆失败跳转地址，默认为/login?error
                .failureUrl("/login?error")
                //用户登录成功处理器
                .successHandler(new MyAuthenticationSuccessHandler())
                //用户登录失败处理器
                .failureHandler(new MyAuthenticationFailureHandler())
        );

        //登录，基本授权方式
//        http.httpBasic(withDefaults());

        //注销
        http.logout(logout -> logout
                //用户注销成功处理器
                .logoutSuccessHandler(new MyLogoutSuccessHandler()));

        //异常处理
        http.exceptionHandling(exception -> exception
                //请求未认证处理器
                .authenticationEntryPoint(new MyAuthenticationEntryPoint())
                //请求未授权处理器
                .accessDeniedHandler(new MyAccessDeniedHandler())
        );

        //缓存处理
        http.sessionManagement(session -> session
                //单用户最大登录数
                .maximumSessions(1)
                //缓存过期处理器
                .expiredSessionStrategy(new MySessionInformationExpiredStrategy()));

        //跨域处理
        http.cors(withDefaults());

        //关闭csrf攻击防御
        http.csrf(AbstractHttpConfigurer::disable);
        return http.build();
    }
}
